#include"RingQueue.hpp"
#include"Thread.hpp"
#include"Task.hpp"
#include<vector>
#include<iostream>
#include<unistd.h>

using namespace ThreadModule;
using ringqueue_t = RingQueue<Task>;
const int num = 5;
void Consumer(ringqueue_t& bq,std::string name)
{
    while(true)
    {
        Task data;
        bq.Pop(&data);
        std::cout << "Consumer handler task: " << "[" << name << "]" << std::endl;
        sleep(1);
        data();
    }
}
void Productor(ringqueue_t& bq,std::string name)
{
    srand(time(nullptr) ^ pthread_self());
    while(true)
    {
        int cnt = 1;
        while(true)
        {
            bq.Enqueue(Download);
            std::cout << "Productor : " << "[" << name << "]" << std::endl;
            // cnt++;
        }   
    }
}
void StartComm(std::vector<Thread<ringqueue_t>>* threads,int i,ringqueue_t& rq,func_t<ringqueue_t> func,const std::string& who)
{
    for(int j = 0; j < i; j++)
    {
        std::string name = "thread-" + std::to_string(j + 1) + who;
        threads->emplace_back(func,rq,name);
        // threads->back().Start();
    }
}
void StartProductor(std::vector<Thread<ringqueue_t>>* threads,int i,ringqueue_t& rq)
{
    StartComm(threads, i, rq, Consumer,"Productor");
}
void StartConsumer(std::vector<Thread<ringqueue_t>>* threads,int i,ringqueue_t& rq)
{
    StartComm(threads, i, rq, Productor, "Consumer");
}
void StartAll(std::vector<Thread<ringqueue_t>> &threads)
{
    for(auto &thread : threads)
    {
        std::cout << "start: " << thread.Name() << std::endl;
        thread.Start();
    }
}
void WaitAllTread(std::vector<Thread<ringqueue_t>>& threads)
{
    for(auto& thread : threads)
    {
        thread.Join();
    }
}
int main()
{
    ringqueue_t* rq = new ringqueue_t(10);
    std::vector<Thread<ringqueue_t>> threads;
    StartProductor(&threads,1, *rq);
    StartConsumer(&threads,5, *rq);
    StartAll(threads);
    WaitAllTread(threads);
    return 0;
}